﻿using System;
using System.Collections.Generic;
using CI;
using CI.Mesopotamia.Dal;
using CI.Misc;
using CI.Organism;
using NUnit.Framework;
using CI.Interfaces;

namespace Mesopotamia.UnitTests
{
    [TestFixture]
    public class ScenarioLocalXMLTests
    {
        private IScenario _scenario;
        private IHostingEnvironment _hostingEnvironment;
        private readonly SimEnv _simEnv = SimEnv.Instance;

        /// <summary>
        /// This sets up the classic "Survival of the Fattest scenario"
        /// </summary>
        [SetUp]
        public void Setup()
        {
            _scenario = new CI.Mesopotamia.ScenarioLocalXML();
            _scenario.FitnessFunction = typeof(CI.Mesopotamia.CollisionDetection).ToString();
            _scenario.ScenarioName = "Survival of the Fattest";
            _scenario.ScenarioDescription = "The evolutionary objective is for the fattest one to reproduce and evolve";
            _scenario.ManifestFile = "InABox.Manifest.xml";
            _scenario.BoundryXRadiusMax = 3.2f;
            _scenario.BoundryYRadiusMax = 2.5f;
            _scenario.BoundryZRadiusMax = 3.2f;
            _scenario.SimulationRestrictions = typeof(CI.Mesopotamia.SurvivalFattest).ToString();
            _scenario.RequiredOrganisms = new List<IScenarioEntityRequirements>();
            _hostingEnvironment = new CI.Mesopotamia.MSRBHost(new MockHostingEnvironmentPhysical(), _scenario);
            var amoebas = new CI.Mesopotamia.Scenario.ScenarioEntityRequirements();
            var iRobots = new CI.Mesopotamia.Scenario.ScenarioEntityRequirements();
            _scenario.RequiredOrganisms.Add(amoebas);
            _scenario.RequiredOrganisms.Add(iRobots);
            amoebas.OrganismType = new Amoeba(new CI.Organism.Organism(_hostingEnvironment), Guid.NewGuid());
            iRobots.OrganismType = new iRobot(new CI.Organism.Organism(_hostingEnvironment), Guid.NewGuid());

            // null out sub sections
            amoebas.OrganismType.Organism = null;
            iRobots.OrganismType.Organism = null;
            amoebas.OrganismType.Guid = Guid.Empty;
            iRobots.OrganismType.Guid = Guid.Empty;
            amoebas.UseFallBackOnly = true;
            iRobots.UseFallBackOnly = false;

            // add the location
            amoebas.Locations.Add(new Location(-1.5f, 0.1f, 1.5f, 0.1f, 0.1f, 0.1f));
            amoebas.Locations.Add(new Location(-1.5f, 0.1f, -1.5f, 0.1f, 0.1f, 0.1f));
            amoebas.Locations.Add(new Location(1.5f, 0.1f, 1.5f, 0.1f, 0.1f, 0.1f));
            amoebas.Locations.Add(new Location(1.5f, 0.1f, -1.5f, 0.1f, 0.1f, 0.1f));
            iRobots.Locations.Add(new Location(0.5f, 0.1f, 0, 0.2f, 0.1f, 0.2f));
            iRobots.Locations.Add(new Location(-0.5f, 0.1f, 0, 0.2f, 0.1f, 0.2f));

            // load dal
            IDAL dal = new TestDAL();
            _hostingEnvironment = dal.LoadHostingEnvironment("dont care", _hostingEnvironment, 0, new List<Guid>());

            // add the fall back organisms
            _scenario.FallBackOrganisms = new List<IOrganism>(_hostingEnvironment.Organisms.Alive);
        }

        /// <summary>
        /// Save the scenario
        /// </summary>
        [Test]
        public void SaveScenarioXML()
        {
            // save the scenario
            _scenario.Save();
        }

        /// <summary>
        /// Load the scenario
        /// </summary>
        [Test]
        public void LoadScenarioXML()
        {
            // save the scenario file so we can load it
            _scenario.Save();

            // try loading it
            IScenario newScenario = new CI.Mesopotamia.ScenarioLocalXML();
            newScenario.ScenarioName = _scenario.ScenarioName;
            newScenario.Load();
        }

        /// <summary>
        /// make sure it checks for null filename
        /// </summary>
        [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "ScenarioName")]
        public void LoadScenarioNullFilenameException()
        {
            _scenario.ScenarioName = null;
            _scenario.Save();
        }

        /// <summary>
        /// make sure it checks for null filename
        /// </summary>
        [Test, ExpectedException(typeof(ArgumentException), ExpectedMessage = "ScenarioName")]
        public void SaveScenarioNullFilenameException()
        {
            _scenario.ScenarioName = null;
            _scenario.Load();
        }

    }

}
